
package com.jf.cloud.distribution.service.impl;

import com.jf.cloud.common.database.dto.PageDTO;
import com.jf.cloud.common.database.util.PageUtil;
import com.jf.cloud.common.database.vo.PageVO;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.util.Arith;
import com.jf.cloud.distribution.constant.DistributionUserIncomeTypeEnum;
import com.jf.cloud.distribution.constant.DistributionWalletBillTypeEnum;
import com.jf.cloud.distribution.dto.DistributionUserWalletDTO;
import com.jf.cloud.distribution.mapper.DistributionUserIncomeMapper;
import com.jf.cloud.distribution.mapper.DistributionUserWalletMapper;
import com.jf.cloud.distribution.model.DistributionUserIncome;
import com.jf.cloud.distribution.model.DistributionUserWallet;
import com.jf.cloud.distribution.model.DistributionUserWalletBill;
import com.jf.cloud.distribution.service.DistributionUserWalletBillService;
import com.jf.cloud.distribution.service.DistributionUserWalletService;
import com.jf.cloud.distribution.vo.DistributionUserWalletVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 分销员钱包信息
 *
 * @author zz
 * @date 2021-08-09 14:14:10
 */
@Service
public class DistributionUserWalletServiceImpl implements DistributionUserWalletService {

    @Autowired
    private DistributionUserWalletMapper distributionUserWalletMapper;
    @Autowired
    private DistributionUserWalletBillService distributionUserWalletBillService;

    @Autowired
    private DistributionUserIncomeMapper distributionUserIncomeMapper;

    @Override
    public PageVO<DistributionUserWallet> page(PageDTO pageDTO) {
        return PageUtil.doPage(pageDTO, () -> distributionUserWalletMapper.list());
    }

    @Override
    public DistributionUserWallet getByWalletId(Long walletId) {
        return distributionUserWalletMapper.getByWalletId(walletId);
    }

    @Override
    public void save(DistributionUserWallet distributionUserWallet) {
        distributionUserWalletMapper.save(distributionUserWallet);
    }

    @Override
    public void update(DistributionUserWallet distributionUserWallet) {
        distributionUserWalletMapper.update(distributionUserWallet);
    }

    @Override
    public void deleteById(Long walletId) {
        distributionUserWalletMapper.deleteById(walletId);
    }

    @Override
    public PageVO<DistributionUserWalletVO> walletPage(PageDTO pageDTO, String userMobile) {
        PageVO<DistributionUserWalletVO> pageVO = PageUtil.doPage(pageDTO, () -> distributionUserWalletMapper.walletPage(userMobile));
        return pageVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWallet(DistributionUserWalletDTO distributionUserWalletDTO, Long userId) {
        //获取到变动前的钱包
        Long walletId = distributionUserWalletDTO.getWalletId();
        DistributionUserWallet oldDistributionUserWallet = distributionUserWalletMapper.getByWalletId(walletId);

        DistributionUserWallet distributionUserWallet = new DistributionUserWallet();
        // 待结算金额和失效金额不能更改-如果平台减少用户待结算金额,且订单待结算的金额大于用户的结算金额, 在系统结算订单后用户待结算金额会小于0 (结算时: 订单待结算金额 - 用户待结算金额 = 用户剩余待结算金额)
        distributionUserWallet.setWalletId(walletId);
        // 修改后的金额
        Long settledAmount =  distributionUserWalletDTO.getChangeAmount();
        // 可提现金额没有变动，不需要继续执行
        if (settledAmount == 0) {
            return;
        }
        // 可提现金额不能小于0
        if (Arith.add(oldDistributionUserWallet.getSettledAmount(), settledAmount) < 0) {
            throw new LuckException("数据已过期，请刷新页面");
        }
        // 设置修改后的可提现金额
        distributionUserWallet.setSettledAmount(settledAmount + oldDistributionUserWallet.getSettledAmount());
        distributionUserWallet.setAccumulateAmount(oldDistributionUserWallet.getAccumulateAmount());
        Long addupAmount = 0L;
        // 提现金额增加时,积累收益也要对应增加
        if (settledAmount > 0) {
            addupAmount = settledAmount;
            distributionUserWallet.setAccumulateAmount(addupAmount + oldDistributionUserWallet.getAccumulateAmount());
        }
        // 根据变化的金额,重新计算要钱包的变动金额
        //修改钱包-只变动提现金额和积累收益
        distributionUserWalletMapper.update(distributionUserWallet);

        // 增加钱包流水记录
        DistributionUserWalletBill distributionUserWalletBill = new DistributionUserWalletBill();
        distributionUserWalletBill.setWalletId(walletId);
        // 改变的金额
        distributionUserWalletBill.setUnsettledAmount(0L);
        distributionUserWalletBill.setSettledAmount(longSub(distributionUserWallet.getSettledAmount(),oldDistributionUserWallet.getSettledAmount()));
        distributionUserWalletBill.setInvalidAmount(0L);
        distributionUserWalletBill.setAccumulateAmount(longSub(distributionUserWallet.getAccumulateAmount(),oldDistributionUserWallet.getAccumulateAmount()));
        distributionUserWalletBill.setRemarksEn("Manual modification");
        distributionUserWalletBill.setRemarks("人工修改");
        // 变更后的金额
        distributionUserWalletBill.setUnsettledAmountAfter(oldDistributionUserWallet.getUnsettledAmount());
        distributionUserWalletBill.setSettledAmountAfter(distributionUserWallet.getSettledAmount());
        distributionUserWalletBill.setInvalidAmountAfter(oldDistributionUserWallet.getInvalidAmount());
        distributionUserWalletBill.setAccumulateAmountAfter(distributionUserWallet.getAccumulateAmount());
        distributionUserWalletBill.setType(DistributionWalletBillTypeEnum.USER.value());
        distributionUserWalletBill.setModifier(userId);

        distributionUserWalletBillService.save(distributionUserWalletBill);

        // 可提现金额发生变动时，增加或减少用户收益明细
        saveDistributionUserIncome(oldDistributionUserWallet, settledAmount);
    }

    @Override
    public DistributionUserWallet getByDistributionUserId(Long distributionUserId) {
        return distributionUserWalletMapper.getByDistributionUserId(distributionUserId);
    }

    @Override
    public int updateWalletAmount(DistributionUserWallet updateWallet) {
        return distributionUserWalletMapper.updateWalletAmount(updateWallet);
    }

    private long longSub(long v1, long v2) {
        BigDecimal decimal = new BigDecimal(Long.valueOf(v1).toString()).subtract(new BigDecimal(Long.valueOf(v2).toString()));
        return decimal.longValue();
    }


    public void saveDistributionUserIncome(DistributionUserWallet oldDistributionUserWallet, Long addupAmount) {
        DistributionUserIncome distributionUserIncome = new DistributionUserIncome();
        distributionUserIncome.setWalletId(oldDistributionUserWallet.getWalletId());
        distributionUserIncome.setIncomeType(DistributionUserIncomeTypeEnum.PLATFORM.value());
        distributionUserIncome.setIncomeAmount(addupAmount);
        distributionUserIncome.setDistributionUserId(oldDistributionUserWallet.getDistributionUserId());
        distributionUserIncome.setCreateTime(new Date());
        distributionUserIncome.setUpdateTime(new Date());
        distributionUserIncomeMapper.save(distributionUserIncome);
    }
}
